package org.robot.actor;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.cfg.StoreCfg;
import org.cfg.SummonCfg;
import org.cfg.cache.StoreCfgCache;
import org.cfg.cache.SummonCfgCache;
import org.constant.FriendConstant;
import org.constant.TaskConstant;
import org.game.module.buildingbo.BuildingBO;
import org.game.module.chatbo.ChatBO;
import org.game.module.core.Core;
import org.game.module.dungeonbo.DungeonBO;
import org.game.module.friendsbo.FriendsBO;
import org.game.module.herobo.HeroBO;
import org.game.module.itembo.ItemBO;
import org.game.module.mailbo.MailBO;
import org.game.module.rolebo.RoleBO;
import org.game.module.storebo.StoreBO;
import org.game.module.summonbo.SummonBO;
import org.game.module.taskbo.TaskBO;
import org.game.protobuf.c2s.C2SChatMsg.ChatMsg;
import org.game.protobuf.c2s.C2SFriendMsg;
import org.game.protobuf.c2s.C2SPlayerMsg;
import org.game.protobuf.c2s.C2SStoreMsg;
import org.game.protobuf.c2s.C2SSummonMsg;
import org.game.protobuf.c2s.C2STaskMsg;
import org.game.protobuf.s2c.S2CShareMsg.ChangeType;
import org.game.protobuf.s2c.S2CFriendMsg;
import org.game.protobuf.s2c.S2CFriendMsg.FriendInfo;
import org.game.protobuf.s2c.S2CTaskMsg;
import org.game.protobuf.s2c.S2CTaskMsg.TaskInfo;

import com.google.common.collect.Maps;
import com.sojoys.artifact.constant.ArtifactErrorCode;
import com.sojoys.artifact.factory.message.IMessage;
import com.sojoys.artifact.factory.session.ISession;
import com.sojoys.artifact.manager.MessageManager;
import com.sojoys.artifact.tools.ToolRandom;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.LogFactory;
import com.xiaoleilu.hutool.util.RandomUtil;

import akka.actor.AbstractActor;
import akka.japi.pf.ReceiveBuilder;
import scala.concurrent.duration.Duration;

/**
 * @author : DengYing
 * @CreateDate : 2018年2月12日 下午11:19:03
 * @Description ：Please describe this document
 */
enum PlayerStatus{
	INIT,		//初始
	DEFAULT,	//默认
	LOADING,	//加载
}
public class ClientPlayerActor extends AbstractActor {
	
	
	static final Log log = LogFactory.get(ClientPlayerActor.class);
	private ISession session;
	private PlayerStatus status = PlayerStatus.INIT;
	private Set<Short> loading = new HashSet<>();
	// 任务缓存
	private Map<String, TaskInfo> taskCache = Maps.newHashMap();
	// 好友缓存
	private Map<Integer, FriendInfo> friendCache = Maps.newHashMap();
	// 道具缓存
	private Map<Integer, FriendInfo> itemCache = Maps.newHashMap();
	
	public ClientPlayerActor(ISession session) {
		super();
		this.session = session;
	}

	@Override
	public Receive createReceive() {
		return ReceiveBuilder.create().match(String.class, x -> {
			switch (x) {
			case "trigger": {
				trigger();
				break;
			}
			case "loadPlayer": {
				status = PlayerStatus.LOADING;
				// 取得全部英雄
				loading.add(HeroBO.getHeros);
				session.sendMessage(MessageManager.me().create(HeroBO.getHeros, new byte[0]));
				// 取得全部精灵
				loading.add(RoleBO.getRoles);
				session.sendMessage(MessageManager.me().create(RoleBO.getRoles, new byte[0]));
				// 取得全部物品
				loading.add(ItemBO.getItems);
				session.sendMessage(MessageManager.me().create(ItemBO.getItems, new byte[0]));
				// 取得全部邮件
				loading.add(MailBO.getMails);
				session.sendMessage(MessageManager.me().create(MailBO.getMails, new byte[0]));
				// 取得全部任务
				loading.add(TaskBO.getTasks);
				session.sendMessage(MessageManager.me().create(TaskBO.getTasks, new byte[0]));
				// 取得全部阵型
				loading.add(Core.getFormations);
				session.sendMessage(MessageManager.me().create(Core.getFormations, new byte[0]));
				// 取得全部建筑
				loading.add(BuildingBO.getBuildingInfo);
				session.sendMessage(MessageManager.me().create(BuildingBO.getBuildingInfo, new byte[0]));
				// 取得副本记录
				loading.add(DungeonBO.getDungeonInfo);
				session.sendMessage(MessageManager.me().create(DungeonBO.getDungeonInfo, new byte[0]));
				// 取得聊天记录
				loading.add(ChatBO.getInitChatInfo);
				session.sendMessage(MessageManager.me().create(ChatBO.getInitChatInfo, new byte[0]));
				// 取得全部好友
				loading.add(FriendsBO.getFriends);
				session.sendMessage(MessageManager.me().create(FriendsBO.getFriends, new byte[0]));
				// 取得商店信息
				loading.add(StoreBO.getStoreInfo);
				C2SStoreMsg.GetStoreInfo.Builder builder = C2SStoreMsg.GetStoreInfo.newBuilder();
				List<StoreCfg> stores = StoreCfgCache.me().getAll();
				for (StoreCfg storeCfg : stores) {
					builder.addCid(storeCfg.getId());
				}
				session.sendMessage(MessageManager.me().create(StoreBO.getStoreInfo, builder.build().toByteArray()));
				break;
			}
			}
		}).match(IMessage.class, msg -> {
			Short cmd = msg.getCommandId();
			if (msg.getStatus() == 0) {
				if (status == PlayerStatus.LOADING) {
					loading.remove(cmd);
					if (loading.isEmpty()) {
						status = PlayerStatus.DEFAULT;
						// 开启触发
						getContext().getSystem().scheduler().schedule(Duration.create(5, TimeUnit.SECONDS),Duration.create(10, TimeUnit.SECONDS), getSelf(), "trigger",getContext().dispatcher(), null);
					}
				}
				switch (cmd) {
				case ItemBO.getItems:{
					break;
				}
				case TaskBO.getTasks:{
					S2CTaskMsg.RespTasks respTasks = S2CTaskMsg.RespTasks.parseFrom(msg.getBody());
					List<TaskInfo> tasks = respTasks.getTaksList();
					for (TaskInfo taskInfo : tasks) {
						if (taskInfo.getCt() == ChangeType.DEFAULT || taskInfo.getCt() == ChangeType.ADD || taskInfo.getCt() == ChangeType.UPDATE) {
							taskCache.put(taskInfo.getId(), taskInfo);
						}else if(taskInfo.getCt() == ChangeType.DELETE) {
							taskCache.remove(taskInfo.getId());
						}
					}
					break;
				}
				case FriendsBO.getFriends:{
					S2CFriendMsg.RespFriends friends = S2CFriendMsg.RespFriends.parseFrom(msg.getBody());
					List<FriendInfo> friendInfos = friends.getFriendsList();
					for (FriendInfo friendInfo : friendInfos) {
						if (friendInfo.getCt() == ChangeType.DEFAULT || friendInfo.getCt() == ChangeType.ADD || friendInfo.getCt() == ChangeType.UPDATE) {
							friendCache.put(friendInfo.getPid(), friendInfo);
						}else if(friendInfo.getCt() == ChangeType.DELETE) {
							taskCache.remove(friendInfo.getPid());
						}
					}
					break;
				}
				case FriendsBO.getRecommendFriends:{
					S2CFriendMsg.RespRecommendFriends recommendFriends = S2CFriendMsg.RespRecommendFriends.parseFrom(msg.getBody());
					List<FriendInfo> friends = recommendFriends.getFriendsList();
					if (!friends.isEmpty()) {
						FriendInfo friend = RandomUtil.randomEle(friends);
						// 发送申请
						C2SFriendMsg.ReqOperate.Builder req = C2SFriendMsg.ReqOperate.newBuilder();
						req.setType(1);
						req.addTargets(friend.getPid());
						session.sendMessage(MessageManager.me().create(FriendsBO.operate, req.build().toByteArray()));
					}
					break;
				}
				}
			}else if(msg.getStatus() == ArtifactErrorCode.UNKNOWN_ERROR) {
				System.out.println(msg);
			}
		}).build();
	}

	/**
	 * 触发
	 */
	private void trigger() {
		int r = RandomUtil.randomInt(1, 10);
		boolean send = false;
		switch (r) {
		case 1:
			send = sendChat();
			break;
		case 2:
			send = changePlayerName();
			break;
		case 3:
			send = summon();
			break;
		case 4:
			send = receiveTask();
			break;
		case 5:
			send = applyFriend();
			break;
		case 6:
			send = consentApply();
			break;
		default:
			heartbeat();
			break;
		}
		// 如果没有发送就发送个心跳
		if (!send) {
			heartbeat();
		}
	}

	

	/**
	 * 发送心跳
	 */
	private boolean heartbeat() {
		session.sendMessage(MessageManager.me().create((short) 262, new byte[0]));
		return true;
	}
	
	/**
	 * 发送聊天
	 */
	private boolean sendChat() {
		ChatMsg.Builder builder = ChatMsg.newBuilder();
		builder.setChannel(1);
		builder.setFun(1);
		builder.setContent(ToolRandom.getFixedLengthChinese(ToolRandom.randInt(5, 20)));
		session.sendMessage(MessageManager.me().create(ChatBO.sendChatMsg, builder.build().toByteArray()));
		return true;
	}
	
	/**
	 * 修改名称
	 */
	private boolean changePlayerName(){
		C2SPlayerMsg.SetPlayerInfo.Builder builder = C2SPlayerMsg.SetPlayerInfo.newBuilder();
		builder.setPlayerName(ToolRandom.getRandomLengthChiness(3, 5));
		builder.setRemark(ToolRandom.getRandomLengthChiness(20, 50));
		session.sendMessage(MessageManager.me().create(Core.setPlayerInfo, builder.build().toByteArray()));
		return true;
	}
	
	/**
	 * 召唤
	 */
	private boolean summon(){
		SummonCfg cfg = RandomUtil.randomEle(SummonCfgCache.me().getAll());
		if (cfg!=null) {
			C2SSummonMsg.Summon.Builder builder = C2SSummonMsg.Summon.newBuilder();	
			builder.setCid(cfg.getId());
			builder.setCost(0);
			session.sendMessage(MessageManager.me().create(SummonBO.summon, builder.build().toByteArray()));
		}
		return true;
	}
	
	/**
	 * 领取任务
	 */
	private boolean receiveTask(){
		TaskInfo taskInfo = null;
		for (Entry<String, TaskInfo> e : taskCache.entrySet()) {
			if (e.getValue().getStatus() == TaskConstant.STATUS_FINISH) {
				taskInfo = e.getValue();
				break;
			}
		}
		if (taskInfo!=null) {
			C2STaskMsg.SubmitTask.Builder builder = C2STaskMsg.SubmitTask.newBuilder();
			builder.setTaskCid(taskInfo.getCid());
			session.sendMessage(MessageManager.me().create(TaskBO.submitTasks, builder.build().toByteArray()));
			return true;
		} else {
			return false;
		}
	}
	
	
	/**
	 * 申请好友
	 */
	private boolean applyFriend(){
		// 取得推荐好友
		C2SFriendMsg.ReqRecommendFriends.Builder builder = C2SFriendMsg.ReqRecommendFriends.newBuilder();
		session.sendMessage(MessageManager.me().create(FriendsBO.getRecommendFriends, builder.build().toByteArray()));
		return true;
	}
	
	/**
	 * 处理好友申请
	 */
	private boolean consentApply() {
		FriendInfo friendInfo = null;
		for (Entry<Integer, FriendInfo> e : friendCache.entrySet()) {
			if (e.getValue().getStatus() == FriendConstant.STATUS_APPLY) {
				friendInfo = e.getValue();
				break;
			}
		}
		
		if (friendInfo!=null) {
			// 发送申请
			C2SFriendMsg.ReqOperate.Builder req = C2SFriendMsg.ReqOperate.newBuilder();
			req.setType(5);
			req.addTargets(friendInfo.getPid());
			session.sendMessage(MessageManager.me().create(FriendsBO.operate, req.build().toByteArray()));
			return true;
		}
		return false;
	}
}
